home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Online / NNTPd / server / xauth.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-09  |  6.8 KB  |  347 lines

  1. #ifndef lint
  2. static char    sccsid[] = "@(#)$Id: xauth.c,v 1.2 1994/12/09 02:52:18 sob Exp sob $";
  3. #endif
  4.  
  5. /*
  6.  * Simple user/password authentication
  7.  *
  8.  * client must supply "xauthinfo user <userid>"
  9.  * followed by "xauthinfo pass <password>"
  10.  * which will be looked up in the server machine's password file.
  11.  * Password must match userid, userid must have gid matching the
  12.  * /etc/group entry for "nntp"
  13.  *
  14.  * note that passwords travel over the network in plaintext.  This
  15.  * can be a problem but isn't easy to remedy.  At least it's as safe
  16.  * as logging in over the network would be
  17.  *
  18.  */
  19.  
  20. #include "common.h"
  21. #include <grp.h>
  22.  
  23. extern timeout();
  24. extern char *crypt();
  25.  
  26. #ifdef    AUTH
  27.  
  28. extern int    Needauth;
  29. extern char    User[];
  30. extern char    Host[];
  31.  
  32. /* forward declarations */
  33. void getpass();
  34. void getuser();
  35.  
  36.  
  37. #ifdef GENAUTH
  38.  
  39. static char *genauth_ret;
  40.  
  41. /* returns:
  42.     -1 for problem (such as no such authenticator etc.)
  43.     0 for authentication succeeded
  44.     1 for authentication failed
  45.  
  46.    It sets and reads the various control parameters like canpost/canread
  47.    etc., based on a INN-like nnrp_access file being given to it via
  48.    the authenticator.
  49.  */
  50. static int
  51. genauth(av)
  52. char    *av[];
  53. {
  54.     char path[COPYSIZE], *fields[6], *p;
  55.     int pid, i, pan[2], exit_status;
  56. #if defined(USG) || defined(BSD_44)
  57.     int status;
  58. #else
  59.     union wait status;
  60. #endif
  61.     struct stat stb;
  62.     char *malloc();
  63.  
  64.     av += 2;
  65.  
  66.     if (!*av) {
  67.         printf("%d no authenticator\r\n", ERR_CMDSYN);
  68.         return(-1);
  69.     }
  70.  
  71.     /* check for ../.  I'd use strstr, but there doesn't appear to
  72.        be any other references for it, and I don't want to break
  73.        portability */
  74.     for (p = av[0]; *p; p++)
  75.         if (*p == '.' && p[1] == '.' && p[2] == '/') {
  76.             printf("%d ../ in authenticator %s\r\n",
  77.                      ERR_CMDSYN, av[0]);
  78.             return(-1);
  79.         }
  80.  
  81.     (void)sprintf(path, "%s/%s", GENAUTH, av[0]);
  82.  
  83.     if (stat(path, &stb) || !(stb.st_mode&S_IXUSR)) {
  84.         printf("%d No such authenticator %s\r\n", ERR_FAULT, av[0]);
  85.         return -1;
  86.     }
  87.  
  88.     /* Create a pipe. */
  89.     if (pipe(pan) < 0) {
  90.         syslog(LOG_ERR, "can't pipe for %s %m", av[0]);
  91.         return -1;
  92.     }
  93.  
  94.     for (i = 0; (pid = fork()) < 0; i++) {
  95.         if (i == 10) {
  96.             printf("%d Can't fork\r\n", ERR_FAULT);
  97.             syslog(LOG_ERR, "can't fork %s %m", av[0]);
  98.             return -1;
  99.         }
  100.         syslog(LOG_INFO, "can't fork %s -- waiting", av[0]);
  101.         (void)sleep(5);
  102.     }
  103.  
  104.     /* Run the child, with redirection. */
  105.     if (pid == 0) {
  106.         (void)close(fileno(stderr));    /* close existing stderr */
  107.         (void)close(pan[0]);
  108.  
  109.         /* stderr goes down the pipe. */
  110.         if (pan[1] != 2) {
  111.             if ((i = dup2(pan[1], 2)) != 2) {
  112.                 syslog(LOG_ERR, "can't dup2 %d to %d got %d %m",
  113.                     pan[1], 2, i);
  114.                 _exit(1);
  115.             }
  116.             (void)close(pan[1]);
  117.         }
  118.  
  119.         /*syslog(LOG_ERR, "path: %s, av[0]: %s, av[1]: %s\n", path, av[0], av[1]);*/
  120.  
  121.         (void)execv(path, av);
  122.         printf("%s\r\n", ERR_COMMAND);
  123.  
  124.         syslog(LOG_ERR, "can't execv %s %m", path);
  125.         _exit(1);
  126.     }
  127.  
  128.     (void)close(pan[1]);
  129.     i = read(pan[0], path, sizeof(path));
  130.  
  131.     if (p = index(path, '\n'))
  132.         *p = '\0';
  133.  
  134.     if (genauth_ret)
  135.         free(genauth_ret);
  136.  
  137.     genauth_ret = malloc(strlen(path)+1);
  138.  
  139.     if (genauth_ret)
  140.         strcpy(genauth_ret, path);
  141.  
  142.     while (pid != wait(&status)) ;
  143. #if defined(USG) || defined(BSD_44)
  144.     exit_status = (status >> 8) & 0xff;
  145. #else
  146.     exit_status = status.w_T.w_Retcode;
  147. #endif
  148.  
  149.     /*syslog(LOG_ERR, "%s (%d) returned: %d %s %d\n", av[0], pid, i, path, status);*/
  150.     /* Split "host:permissions:user:pass:groups" into fields. */
  151.     for (fields[0] = path, i = 0, p = path; *p; p++)
  152.         if (*p == ':') {
  153.             *p = '\0';
  154.             fields[++i] = p + 1;
  155.         }
  156.  
  157.     canread = canpost = canxfer = 0;
  158.  
  159.     for (p = fields[1]; *p; p++)
  160.     if (index("Rr", *p))
  161.         canread = 1;
  162.     else if (index("Pp", *p))
  163.         canpost = 1;
  164.     else if (index("Xx", *p))
  165.         canxfer = 1;
  166.     else if (index("Bb", *p))
  167.         canread = canxfer = 1;
  168.  
  169.     (void)strcpy(Host, fields[0]);
  170.     (void)strcpy(User, fields[2]);
  171.  
  172.     /*(void)strcpy(pass, fields[3]);*/
  173.  
  174.     if (strcmp(fields[4], "*") == 0)
  175.         fields[4] = "any";
  176.     ngpermcount = get_nglist(&ngpermlist, fields[4]);
  177.  
  178.     /*(void)strcpy(writeaccess, fields[5]); future work? */
  179.  
  180.     /*for (i = 0; ngpermlist[i]; i++)
  181.         printf("permlist[%d] = %s\n", i, ngpermlist[i]);*/
  182.  
  183.     return !exit_status;
  184. }
  185.  
  186. #endif
  187.  
  188. static int
  189. argcount(cnt, shouldbe)
  190. int cnt;
  191. int shouldbe;
  192. {
  193.     if (cnt != shouldbe) {
  194.         printf("%d Syntax error\r\n", ERR_CMDSYN);
  195.         fflush(stdout);
  196.         return(1);
  197.     }
  198.     return(0);
  199. }
  200.  
  201. void
  202. doxauthcap(argc,argv)
  203. int argc;
  204. char *argv[];
  205. {
  206.     printf("%d authcap not implemented\r\n", ERR_COMMAND);
  207.     fflush(stdout);
  208.     return;
  209. }
  210.  
  211. void
  212. doxauthsys(argc,argv)
  213. int argc;
  214. char *argv[];
  215. {
  216.     printf("%d authsys not implemented\r\n", ERR_COMMAND);
  217.     fflush(stdout);
  218.     return;
  219. }
  220.  
  221. void
  222. doxauthinfo(argc,argv)
  223. int argc;
  224. char *argv[];
  225. {
  226.     if (!Needauth) {
  227.         printf("%d Authorization already completed\r\n", ERR_AUTHREJ);
  228.         fflush(stdout);
  229.         return;
  230.     }
  231.  
  232.     if (!strcasecmp(argv[1],"user")) {
  233.         if (argcount(argc, 3))
  234.             return;
  235.         if (strlen(User)) {
  236.             printf("%d USER already specified\r\n", ERR_AUTHREJ);
  237.             fflush(stdout);
  238.             return;
  239.         }
  240.         getuser(argv[2]);
  241.         return;
  242.     }
  243.  
  244.     if (!strcasecmp(argv[1],"pass")) {
  245.         if (argcount(argc, 3))
  246.             return;
  247.         if (strlen(User) < 1) {
  248.             printf("%d USER required first\r\n", ERR_AUTHREJ);
  249.             fflush(stdout);
  250.             return;
  251.         }
  252.         getpass(argv[2]);
  253.         return;
  254.     }
  255. #ifdef GENAUTH
  256.     if (!strcasecmp(argv[1], "generic")) {
  257.         strcpy(User, "<none>");
  258.         switch (genauth(argv)) {
  259.             case 1:
  260.                 syslog(LOG_NOTICE, "%s auth %s@%s (%s)",
  261.                      hostname, User, Host, genauth_ret ?
  262.                         genauth_ret: "");
  263.                 printf("%d Authentication succeeded\r\n",
  264.                      OK_AUTH);
  265.                 fflush(stdout);
  266.                 Needauth = 0;
  267.                 break;
  268.             case 0:
  269.                 syslog(LOG_NOTICE, "%s bad_auth %s", hostname,
  270.                      User);
  271.                 printf("%d Authentication failed\r\n", ERR_ACCESS);
  272.                 fflush(stdout);
  273.                 exit(1);
  274.             default:
  275.                 /* lower level has issued Reply */
  276.                 break;
  277.         }
  278.         return;
  279.     }
  280. #endif
  281.     
  282. #ifdef    GENAUTH
  283.     printf("%d user Name|pass Password|generic <prog> <args>\r\n", ERR_CMDSYN);
  284. #else
  285.     printf("%d user Name|pass Password\r\n", ERR_CMDSYN);
  286. #endif
  287.     fflush(stdout);
  288. }
  289.  
  290. /* get userid and prompt for password */
  291. void
  292. getuser(p)
  293. char *p;
  294. {
  295.     strncpy(User,p,8);
  296.     User[8] = 0;
  297.     /* get the password */
  298.     printf("%d PASS required\r\n", NEED_AUTHDATA);
  299.     fflush(stdout);
  300. }
  301.  
  302. /* password */
  303. void
  304. getpass(p)
  305. char *p;
  306. {
  307.     static char pass[10];
  308.     char *namep;
  309.     struct passwd *pwd;
  310.     struct group *grp;
  311.     extern struct group *getgrnam();
  312.  
  313.     strncpy(pass,p,8);
  314.     pass[8] = 0;
  315.     /* check for valid login */
  316.     pwd = getpwnam(User);
  317.     namep = NULL;
  318.  
  319.     if (pwd != NULL)
  320.         namep = crypt(pass, pwd->pw_passwd);
  321.     
  322.     grp = getgrnam("nntp");
  323.  
  324.     if (grp == NULL || pwd == NULL || namep == NULL
  325.             || strcmp(namep, pwd->pw_passwd)
  326.             || pwd->pw_gid != grp->gr_gid) {
  327. #ifdef SYSLOG
  328.         syslog(LOG_ERR, "AUTHENTICATION ERROR");
  329. #endif
  330.         printf("%d Authentication error\r\n",ERR_ACCESS);
  331.         (void) fflush(stdout);
  332.         (void) fflush(stdout);
  333.         exit(1);
  334.     }
  335.  
  336. #ifdef SYSLOG
  337. #ifdef LOG
  338.     syslog(LOG_INFO, "user %s", User);
  339. #endif
  340. #endif
  341.     printf("%d Authentication accepted\r\n",OK_AUTH);
  342.     fflush(stdout);
  343.     Needauth = 0;
  344. }
  345.  
  346. #endif /* AUTH */
  347.